package cn.kgc.commons.advice;


import cn.kgc.commons.annotation.IgnoreResultAdviceAnnotation;
import cn.kgc.commons.vo.Result;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

/**
 * <p>将控制器中返回的结果封装成Result</p>
 *
 *
 * gateway 引用commons的时候排除springboot-starter-web,所以添加
 * gateway模块不能使用@ControllerAdvice注解
 * 可以使用@ConditionalOnClass(ResponseBodyAdvice.class)注解
 *
 * 判断项目中是否含有ResponseBodyAdvice类，如果有就引了springboot-starter-web依赖
 * @ConditionalOnClass(ResponseBodyAdvice.class)
 */
@ConditionalOnClass(ResponseBodyAdvice.class)
@ControllerAdvice({"cn.kgc.controller","cn.kgc.base.controller"})
public class ResultAdvice implements ResponseBodyAdvice<Object> {

    @Override
    public boolean supports(MethodParameter returnType, Class converterType) {
        //如果控制器中的方法上 添加了该注解,该方法的返回值,不需要在封装到Result对象中。
        if(returnType.getMethod()
                .isAnnotationPresent(IgnoreResultAdviceAnnotation.class)){
            return false;
        }
        return true;
    }

    //将控制器中方法的返回值封装成Result对象
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType,
                                  ServerHttpRequest request, ServerHttpResponse response) {
        String requestUrl=request.getURI().toString();
        if(body==null){ //控制器的返回值是null,将结果封装成result对象
            return Result.builder().code(200).data(null)
                    .message("success").requestURL(requestUrl).build();
        }else if(body instanceof Result) {
            return (Result) body;
        }else if(body instanceof String) {
            return Result.builder().code(200).data(body)
                    .message("success").requestURL(requestUrl).build();
        }else{
            return Result.builder().code(200).data(body)
                    .message("success").requestURL(requestUrl).build();
        }
    }
}